'/
' GUI Library
' Written by Anton Berlin, 2010.
' 
' =========================================================================
' 
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU Lesser General Public License as published
' by the Free Software Foundation; either version 3 of the License.
' 
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
' 
' You should have received a copy of the GNU Lesser General Public License
' along with this program; if not, write to the Free Software
' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
'/

superstrict

import "GUI_Gadget.bmx"
import "GUI_Def.bmx"

import "../strutil/strutil.bmx"

type GUI_Slider extends GUI_Gadget

	'// -------------------------------------------------------------------------------------------------------------
	'// Update this gadget.
	'// -------------------------------------------------------------------------------------------------------------
	method update()
	
		if (not mouseHovering()) ..
			return;
		
		if (mouseDown(1)) ..
			computeValue(mouseX());
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Compute the value, based on the mouse coordinate. It snaps to the nearest tick.
	'// -------------------------------------------------------------------------------------------------------------
	method computeValue(mx:int)
	
		mx :- m_posX;
		
		local value:int = int(double(mx) / m_width * 100.0);
		value = floor((value + m_tickFrequency / 2) / m_tickFrequency) * m_tickFrequency;
		
		setValue(value, true);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw this gadget.
	'// -------------------------------------------------------------------------------------------------------------
	method draw()
	
		if (not m_visible) ..
			return;
		
		'// Setup the default drawing settings.
		drawutil.setColorInit(m_primitiveR, m_primitiveG, m_primitiveB);
		drawutil.setAlphaInit(m_transparency);
		
		'// Draw the design of the gadget.
		design();
		
		'// Reset drawing settings.
		drawutil.resetColor();
		drawutil.resetAlpha();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw the design of this gadget.
	'// -------------------------------------------------------------------------------------------------------------
	method design()
	
		local width:double = m_width - 8;
		local range:int = m_maxValue - m_minValue;
		local tick:int = 0;
		local tickLength:double = width / m_maxValue;
		
		local brightR:byte = min(m_primitiveR * 1.5, 255);
		local brightG:byte = min(m_primitiveG * 1.5, 255);
		local brightB:byte = min(m_primitiveB * 1.5, 255);
		
		local darkR:byte = max(m_primitiveR * 0.33, 0);
		local darkG:byte = max(m_primitiveG * 0.33, 0);
		local darkB:byte = max(m_primitiveB * 0.33, 0);
		
		setColor(darkR, darkG, darkB);
		drawLine(m_posX + 4, m_posY + m_height * 0.25, m_posX + m_width - 4, m_posY + m_height * 0.25);
		setColor(brightR, brightG, brightB);
		drawLine(m_posX + 4, m_posY + m_height * 0.25 + 1, m_posX + m_width - 4, m_posY + m_height * 0.25 + 1);
		
		setColor(m_tickColorR, m_tickColorG, m_tickColorB);
		
		while (tick <= range)
		
			drawLine( ..
				double(m_posX) + 4 + tickLength * tick, ..
				m_posY + m_height * 0.60, ..
				double(m_posX) + 4 + tickLength * tick, ..
				m_posY + m_height * 0.75);
			
			tick :+ m_tickFrequency;
		
		end while
		
		drawDragger(brightR, brightG, brightB, darkR, darkG, darkB, tickLength);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw the scrollbar.
	'// -------------------------------------------------------------------------------------------------------------
	method drawDragger(brightR:byte, brightG:byte, brightB:byte, darkR:byte, darkG:byte, darkB:byte, tickLength:double)
	
		local startX:int = m_posX + tickLength * m_value;
		local startY:int = m_posY + m_height * 0.25 - 5;
		
		setColor(m_primitiveR, m_primitiveG, m_primitiveB);
		drawRect(startX, startY, 8, 12);
		
		setColor(brightR, brightG, brightB);
		drawLine(startX, startY, startX + 8, startY);
		drawLine(startX, startY, startX, startY + 12);
		
		setColor(darkR, darkG, darkB);
		drawLine(startX + 8, startY, startX + 8, startY + 12);
		
		setColor(m_primitiveR * 0.6, m_primitiveG * 0.6, m_primitiveB * 0.6);
		drawLine(startX, startY + 12, startX + 4, startY + 16);
		drawLine(startX + 4, startY + 16, startX + 8, startY + 12);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set the current value of the slider. This also executes the specified method hook.
	'// -------------------------------------------------------------------------------------------------------------
	method setValue(value:int, clickedToSetValue:byte = false)
	
		m_value = min(max(value, m_minValue), m_maxValue);
		
		if (m_methodHook and clickedToSetValue) ..
			m_event = GUI_Event.create(GUI_Event.EVENT_INVOKE_METHOD, m_methodHook, m_hookedObject);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set the minimum value of the slider
	'// -------------------------------------------------------------------------------------------------------------
	method setMinValue(value:int)
	
		m_minValue = max(value, 0);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set the maximum value of the slider.
	'// -------------------------------------------------------------------------------------------------------------
	method setMaxValue(value:int)
	
		m_maxValue = max(value, m_minValue);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set the color of the ticks.
	'// -------------------------------------------------------------------------------------------------------------
	method setTickColor(r:byte, g:byte, b:byte)
	
		m_tickColorR = r;
		m_tickColorG = g;
		m_tickColorB = b;
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set the tick frequency.
	'// -------------------------------------------------------------------------------------------------------------
	method setTickFrequency(value:int)
	
		m_tickFrequency = min(max(value, m_minValue), m_maxValue);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Tick color.
	'// -------------------------------------------------------------------------------------------------------------
	field m_tickColorR:byte;
	field m_tickColorG:byte;
	field m_tickColorB:byte;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Current value of the slider.
	'// -------------------------------------------------------------------------------------------------------------
	field m_value:int;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Tick frequency.
	'// -------------------------------------------------------------------------------------------------------------
	field m_tickFrequency:int;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Minimum value of the slider.
	'// -------------------------------------------------------------------------------------------------------------
	field m_minValue:int;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Maximum value of the slider.
	'// -------------------------------------------------------------------------------------------------------------
	field m_maxValue:int;

end type

